﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Diagnostics;
using Devart.Data.Oracle;
using Wintellect.PowerCollections;
using DbSharp.Framework.Storage.IO;
using DbSharp.Framework.DbObject;
using DbSharp.Framework.Driver;


namespace DbSharp.Framework.Assertion.Xml
{
    partial class AssertionHelper
    {
        [Obsolete]
        private static bool IsValidArgsForSetCountAndNumAxis(object enumerableArg, object intervalOfNumAxis)
        {
            decimal lowValue, highValue;
            bool includeLowValue, includeHighValue;
            if (IsEnumerable(enumerableArg))
            {
                if (IsNumberAxis(intervalOfNumAxis, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }

        private static bool IsValidArgsForSetCountAndNumAxis_Old(object enumerableArg, object intervalOfNumAxis, ITestDataSource intervalDbPlugin)
        {
            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;
            if (IsEnumerable(enumerableArg))
            {
                if (IsNumberAxis(intervalOfNumAxis, intervalDbPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }


        private static bool IsValidArgsForSetCountAndNumAxis(object actual, object expected, ITestDataSource expectedPlugin)
        {
            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;
            if (IsEnumerable(actual))
            {
                if (IsEnumerable(expected))
                    return true;
                else if (IsNumberAxis(expected, expectedPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }


        [Obsolete]
        private static bool IsValidArgsForIntervalOfAxis(object arg, object intervalOfNumAxis)
        {
            decimal lowValue, highValue;
            bool includeLowValue, includeHighValue;
            if (IsEnumerable(arg))
            {
                if (IsNumberAxis(intervalOfNumAxis, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else if (IsNumber(arg))
            {
                if (IsNumberAxis(intervalOfNumAxis, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }

        private static bool IsValidArgsForIntervalOfAxis(object arg, int argElementValueType, ITestDataSource argPlugin, object intervalOfNumAxis, ITestDataSource intervalPlugin)
        {
            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;
            if (IsEnumerable(arg))
            {
                if (IsNumberAxis(intervalOfNumAxis, intervalPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else if (IsNumber(arg, argElementValueType, argPlugin))
            {
                if (IsNumberAxis(intervalOfNumAxis, intervalPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }



        [Obsolete]
        private static Decimal ConvertToDecimal(string text)
        {
            if (text.Equals("min", StringComparison.OrdinalIgnoreCase))
                return Decimal.MinValue;
            else if (text.Equals("max", StringComparison.OrdinalIgnoreCase))
                return decimal.MaxValue;
            else
                return Convert.ToDecimal(text);
        }

        private static OracleNumber ConvertToDecimal(string valueText, int valueType, ITestDataSource dbPlugin)
        {
            valueText = valueText.Trim();
            if (valueText.Equals("min", StringComparison.OrdinalIgnoreCase))
                return OracleNumber.MinValue;
            else if (valueText.Equals("max", StringComparison.OrdinalIgnoreCase))
                return OracleNumber.MaxValue;
            else
                return dbPlugin.FieldPersistenceService.RestoreStringToLargeDecimal(valueText, valueType);
        }


        [Obsolete]
        public static void VerifyInIntervalOfNumAxisClaimArgs(object actual, object expected)
        {
            if (IsValidArgsForIntervalOfAxis(actual, expected) == false)
            {
                if (IsValidArgsForIntervalOfAxis(expected, actual) == false)
                {
                    string message = @"One argument must be list or scalar only including number, and another argument must be one interval of number axis.";
                    throw new ArgumentException(message);
                }
            }
        }


        public static void VerifyInIntervalOfNumAxisClaimArgs(object actual, List<FieldMetaData> actualMetaData, ITestDataSource actualPlugin, object expected, ITestDataSource expectedPlugin)
        {
            if (IsValidArgsForIntervalOfAxis(actual, actualMetaData[0].FieldDataType, actualPlugin, expected, expectedPlugin) == false)
            {
                string message = @"actual argument must be decimal list or decimal scalar, and expected argument must be one interval of number axis.";
                throw new ArgumentException(message);
            }
        }

        public static void VerifyInIntervalOfNumAxisClaimArgs_Old(object actual, List<FieldMetaData> actualMetaData, ITestDataSource actualPlugin, object expected, List<FieldMetaData> expectedMetaData, ITestDataSource expectedPlugin)
        {
            if (IsValidArgsForIntervalOfAxis(actual, actualMetaData[0].FieldDataType, actualPlugin, expected, expectedPlugin) == false)
            {
                if (IsValidArgsForIntervalOfAxis(expected, expectedMetaData[0].FieldDataType, expectedPlugin, actual, actualPlugin) == false)
                {
                    string message = @"One argument must be list or scalar only including number, and another argument must be one interval of number axis.";
                    throw new ArgumentException(message);
                }
            }
        }

        [Obsolete]
        public static void VerifySetCountInIntervalOfNumAxisClaimArgs(object actual, object expected)
        {
            if (IsValidArgsForSetCountAndNumAxis(actual, expected) == false)
            {
                if (IsValidArgsForSetCountAndNumAxis(expected, actual) == false)
                {
                    string message = @"One argument must be list, and another argument must be one interval of number axis.";
                    throw new ArgumentException(message);
                }
            }
        }

        public static void VerifySetCountInIntervalOfNumAxisClaimArgs(object actual, ITestDataSource actualPlugin, object expected, ITestDataSource expectedPlugin)
        {
            if (IsValidArgsForSetCountAndNumAxis(actual, expected, expectedPlugin) == false)
            {
                string message = @"Actual argument must be list, and expected argument must be one list or one interval of number axis.";
                throw new ArgumentException(message);
            }
        }

        public static void VerifySetCountInIntervalOfNumAxisClaimArgs_Old(object actual, ITestDataSource actualPlugin, object expected, ITestDataSource expectedPlugin)
        {
            if (IsValidArgsForSetCountAndNumAxis_Old(actual, expected, expectedPlugin) == false)
            {
                if (IsValidArgsForSetCountAndNumAxis_Old(expected, actual, actualPlugin) == false)
                {
                    string message = @"One argument must be list, and another argument must be one interval of number axis.";
                    throw new ArgumentException(message);
                }
            }
        }

        [Obsolete]
        public static bool IsNumber(object obj)
        {
            try
            {
                Convert.ToDecimal(obj);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool IsNumber(object obj, int objDbType, ITestDataSource dbPlugin)
        {
            try
            {
                dbPlugin.FieldPersistenceService.RestoreStringToLargeDecimal(obj.ToString(), objDbType);
                //Convert.ToDecimal(obj);
                return true;
            }
            catch
            {
                return false;
            }
        }

        [Obsolete]
        public static bool IsNumberAxis(object interval, out decimal lowValue, out decimal highValue, out bool includeLowValue, out bool includeHighValue)
        {
            bool result = true;
            lowValue = 0;
            includeLowValue = true;
            highValue = 0;
            includeHighValue = true;
            bool leftOpen = false;
            bool rightOpen = false;
            string leftString;
            string rightString;
            string[] boundaries;
            try
            {
                string intervalText = interval.ToString().Trim();
                if (intervalText[0] == '(')
                    leftOpen = true;
                else if (intervalText[0] == '[')
                    leftOpen = false;
                else
                    return false;

                if (intervalText[intervalText.Length - 1] == ')')
                    rightOpen = true;
                else if (intervalText[intervalText.Length - 1] == ']')
                    rightOpen = false;
                else
                    return false;

                intervalText = intervalText.Substring(1);
                intervalText = intervalText.Substring(0, intervalText.Length - 1);

                intervalText = intervalText.Trim();
                boundaries = intervalText.Split(',');

                leftString = boundaries[0].Trim();
                rightString = boundaries[1].Trim();


                decimal leftValue, rightValue;
                leftValue = ConvertToDecimal(leftString);
                rightValue = ConvertToDecimal(rightString);
                if (Decimal.Compare(rightValue, leftValue) >= 0)
                {
                    highValue = rightValue;
                    includeHighValue = !rightOpen;
                    lowValue = leftValue;
                    includeLowValue = !leftOpen;
                }
                else
                {
                    highValue = leftValue;
                    includeHighValue = !leftOpen;
                    lowValue = rightValue;
                    includeLowValue = !rightOpen;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }


        public static bool IsNumberAxis(object interval, ITestDataSource intervalPlugin, out OracleNumber lowValue, out OracleNumber highValue, out bool includeLowValue, out bool includeHighValue)
        {
            bool result = true;
            lowValue = 0;
            includeLowValue = true;
            highValue = 0;
            includeHighValue = true;
            bool leftOpen = false;
            bool rightOpen = false;
            string leftString;
            string rightString;
            string[] boundaries;
            try
            {
                string intervalText = interval.ToString().Trim();
                if (intervalText[0] == '(')
                    leftOpen = true;
                else if (intervalText[0] == '[')
                    leftOpen = false;
                else
                    return false;

                if (intervalText[intervalText.Length - 1] == ')')
                    rightOpen = true;
                else if (intervalText[intervalText.Length - 1] == ']')
                    rightOpen = false;
                else
                    return false;

                intervalText = intervalText.Substring(1);
                intervalText = intervalText.Substring(0, intervalText.Length - 1);

                intervalText = intervalText.Trim();
                boundaries = intervalText.Split(',');

                leftString = boundaries[0].Trim();
                rightString = boundaries[1].Trim();


                OracleNumber leftValue, rightValue;
                int valueType = intervalPlugin.FieldPersistenceService.NumberTypeWhenParseLiteral;
                leftValue = ConvertToDecimal(leftString, valueType, intervalPlugin);
                rightValue = ConvertToDecimal(rightString, valueType, intervalPlugin);
                if (rightValue.CompareTo(leftValue) >= 0)
                {
                    highValue = rightValue;
                    includeHighValue = !rightOpen;
                    lowValue = leftValue;
                    includeLowValue = !leftOpen;
                }
                else
                {
                    highValue = leftValue;
                    includeHighValue = !leftOpen;
                    lowValue = rightValue;
                    includeLowValue = !rightOpen;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }


        [Obsolete]
        public static bool IsInRange(string value, decimal lowValue, decimal highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result = true;
            try
            {
                decimal value1 = Convert.ToDecimal(value);
                int high = Decimal.Compare(highValue, value1);
                if (includeHighValue)
                    result = (high >= 0);
                else
                    result = (high > 0);

                if (result == true)
                {
                    int low = Decimal.Compare(value1, lowValue);
                    if (includeLowValue)
                        result = (low >= 0);
                    else
                        result = (low > 0);
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }

        public static bool IsInRange(string value, int valueType, ITestDataSource dbPlugin, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result = true;
            try
            {
                OracleNumber value1 = dbPlugin.FieldPersistenceService.RestoreStringToLargeDecimal(value, valueType);
                int highResult = highValue.CompareTo(value1);
                if (includeHighValue)
                    result = (highResult >= 0);
                else
                    result = (highResult > 0);

                if (result == true)
                {
                    int lowResult = value1.CompareTo(lowValue);
                    if (includeLowValue)
                        result = (lowResult >= 0);
                    else
                        result = (lowResult > 0);
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }

        public static bool IsInRange2(string value, int valueType, ITestDataSource dbPlugin, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue, DecimalRangeChecker decimalRangeChecker)
        {
            bool result = true;
            try
            {
                OracleNumber value1 = dbPlugin.FieldPersistenceService.RestoreStringToLargeDecimal(value, valueType);
                result = decimalRangeChecker(value1, lowValue, highValue, includeLowValue, includeHighValue);
            }
            catch
            {
                result = false;
            }
            return result;
        }
    }





    /// <summary>
    /// Determines wheter the number value of one operand is in interval of number axis represented by another operand
    /// Operand: one is number value, another is string format of number axis interval, such as (0,1) or (0,1] or [0,1) or [0,1]
    /// Result : true if the the number value of one operand is in interval of number axis represented by another operand
    /// </summary>
    class DecimalElementIsInNumAxisAssertion_Old : IAssertion
    {

        private bool IsInRange(object val, List<FieldMetaData> valMetaList, ITestDataSource valPlugin, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result = true;
            if (AssertionHelper.IsEnumerable(val))
            {
                IEnumerable<XElement> list = (IEnumerable<XElement>)val;
                foreach (var item in list)
                {
                    if (!AssertionHelper.IsInRange(item.Value, valMetaList[0].FieldDataType, valPlugin, lowValue, highValue, includeLowValue, includeHighValue))
                    {
                        result = false;
                        break;
                    }
                }
            }
            else if (AssertionHelper.IsNumber(val, valMetaList[0].FieldDataType, valPlugin))
                result = AssertionHelper.IsInRange(val.ToString(), valMetaList[0].FieldDataType, valPlugin, lowValue, highValue, includeLowValue, includeHighValue);
            else
                result = false;
            return result;
        }

        #region IAssertion Members

        public bool Claim(object actual, object expected, List<FieldMetaData> actualMetaData, List<FieldMetaData> expectedMetaData, ITestDataSource actualPlugin, ITestDataSource expectedPlugin)
        {
            AssertionHelper.VerifyInIntervalOfNumAxisClaimArgs_Old(actual, actualMetaData, actualPlugin, expected, expectedMetaData, expectedPlugin);

            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;
            bool isInterval = AssertionHelper.IsNumberAxis(actual, actualPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue);
            if (isInterval)
            {
                return IsInRange(expected, expectedMetaData, expectedPlugin, lowValue, highValue, includeLowValue, includeHighValue);
            }
            else
            {
                AssertionHelper.IsNumberAxis(expected, expectedPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue);
                return IsInRange(actual, actualMetaData, actualPlugin, lowValue, highValue, includeLowValue, includeHighValue);
            }
        }

        #endregion
    }

    /// <summary>
    /// to check value is between lowValue and highValue or not
    /// </summary>
    /// <param name="value"></param>
    /// <param name="lowValue"></param>
    /// <param name="highValue"></param>
    /// <param name="includeLowValue"></param>
    /// <param name="includeHighValue"></param>
    /// <returns>true if in range, else false</returns>
    delegate bool DecimalRangeChecker(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue);



    /// <summary>
    /// This is collection of DecimalRangeChecker delegate
    /// </summary>
    static class DecimalRangeCheckerPool
    {
        public static bool DecimalIsInNumberAxis(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result;
            int highResult = highValue.CompareTo(value);
            if (includeHighValue)
                result = (highResult >= 0);
            else
                result = (highResult > 0);

            if (result == true)
            {
                int lowResult = value.CompareTo(lowValue);
                if (includeLowValue)
                    result = (lowResult >= 0);
                else
                    result = (lowResult > 0);
            }
            return result;
        }

        public static bool DecimalIsGreater(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result;
            int lowResult = value.CompareTo(lowValue);
            result = (lowResult > 0);
            return result;
        }

        public static bool DecimalIsGreaterOrEqual(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result;
            int lowResult = value.CompareTo(lowValue);
            result = (lowResult >= 0);
            return result;
        }

        public static bool DecimalIsEqual(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result;
            int lowResult = value.CompareTo(lowValue);
            result = (lowResult == 0);
            return result;
        }

        public static bool DecimalIsLess(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result;
            int highResult = highValue.CompareTo(value);
            result = (highResult >= 0);
            return result;
        }

        public static bool DecimalIsLessOrEqual(OracleNumber value, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            bool result;
            int highResult = highValue.CompareTo(value);
            result = (highResult > 0);
            return result;
        }
    }

    abstract class DecimalElementInRangeAssertionBase : IAssertion
    {
        public abstract DecimalRangeChecker GetDecimalElementRangeChecker();


        /// <summary>
        /// convert the expected object into interval of num axis if it is one interval
        /// </summary>
        /// <param name="expected"></param>
        /// <returns></returns>
        public abstract string ConvertExpectedToInterval(object expected);

        private bool IsInRange(object val, List<FieldMetaData> valMetaList, ITestDataSource valPlugin, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue, DecimalRangeChecker checker)
        {
            bool result = true;
            //NumberRangeChecker inRangeOfNumberAxis = new NumberRangeChecker(NumberRangeCheckerPool.InRangeOfNumberAxis);
            if (AssertionHelper.IsEnumerable(val))
            {
                IEnumerable<XElement> list = (IEnumerable<XElement>)val;
                foreach (var item in list)
                {
                    if (!AssertionHelper.IsInRange2(item.Value, valMetaList[0].FieldDataType, valPlugin, lowValue, highValue, includeLowValue, includeHighValue, checker))
                    {
                        result = false;
                        break;
                    }
                }
            }
            else if (AssertionHelper.IsNumber(val, valMetaList[0].FieldDataType, valPlugin))
                result = AssertionHelper.IsInRange2(val.ToString(), valMetaList[0].FieldDataType, valPlugin, lowValue, highValue, includeLowValue, includeHighValue, checker);
            else
                result = false;
            return result;
        }


        #region IAssertion Members

        public bool Claim(object actual, object expected, List<FieldMetaData> actualMetaData, List<FieldMetaData> expectedMetaData, ITestDataSource actualPlugin, ITestDataSource expectedPlugin)
        {
            string interval = ConvertExpectedToInterval(expected);
            AssertionHelper.VerifyInIntervalOfNumAxisClaimArgs(actual, actualMetaData, actualPlugin, interval, expectedPlugin);

            DecimalRangeChecker checker = GetDecimalElementRangeChecker();

            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;

            AssertionHelper.IsNumberAxis(interval, expectedPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue);
            return IsInRange(actual, actualMetaData, actualPlugin, lowValue, highValue, includeLowValue, includeHighValue, checker);
        }

        #endregion
    }


    class DecimalElementIsEqualAssertion : DecimalElementInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsEqual);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string intervalFmt = "[{0},{1}]";
            string interval = string.Format(intervalFmt, expected.ToString(), expected.ToString());
            return interval;
        }
    }

    class DecimalElementIsGreaterAssertion : DecimalElementInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsGreater);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string intervalFmt = "({0},{1})";
            string interval = string.Format(intervalFmt, expected.ToString(), "max");
            return interval;
        }
    }

    class DecimalElementIsGreaterOrEqualAssertion : DecimalElementInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsGreaterOrEqual);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string intervalFmt = "[{0},{1})";
            string interval = string.Format(intervalFmt, expected.ToString(), "max");
            return interval;
        }
    }


    class DecimalElementIsLessAssertion : DecimalElementInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsLess);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string intervalFmt = "({0},{1})";
            string interval = string.Format(intervalFmt, "min", expected.ToString());
            return interval;
        }
    }


    class DecimalElementIsLessOrEqualAssertion : DecimalElementInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsLessOrEqual);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string intervalFmt = "({0},{1}]";
            string interval = string.Format(intervalFmt, "min", expected.ToString());
            return interval;
        }
    }




    class DecimalElementIsInNumAxisAssertion : DecimalElementInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsInNumberAxis);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            //expected should be one interval of number axis
            string interval = expected.ToString();
            return interval;
        }
    }

    /// <summary>
    /// Determines wheter the element count of one operand is in interval of number axis represented by another operand
    /// Operand: one operand is set, another is string format of number axis interval, such as (0,1) or (0,1] or [0,1) or [0,1]
    /// Result : true if the element count of one operand is in interval of number axis represented by another operand
    /// </summary>
    class RecordCountIsInNumAxisAssertion_Old : IAssertion
    {

        private bool InRange(IEnumerable<XElement> enumerableArg, ITestDataSource enumerableArgPlugin, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue)
        {
            int count1 = enumerableArg.Count();
            int count1Type = enumerableArgPlugin.FieldPersistenceService.NumberTypeWhenParseLiteral;
            return AssertionHelper.IsInRange(count1.ToString(), count1Type, enumerableArgPlugin, lowValue, highValue, includeLowValue, includeHighValue);
        }


        #region IAssertion Members

        public bool Claim(object actual, object expected, List<FieldMetaData> actualMetaData, List<FieldMetaData> expectedMetaData, ITestDataSource actualPlugin, ITestDataSource expectedPlugin)
        {
            AssertionHelper.VerifySetCountInIntervalOfNumAxisClaimArgs_Old(actual, actualPlugin, expected, expectedPlugin);
            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;
            bool isInterval = AssertionHelper.IsNumberAxis(expected, expectedPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue);
            if (isInterval)
            {
                return InRange((IEnumerable<XElement>)actual, actualPlugin, lowValue, highValue, includeLowValue, includeHighValue);
            }
            else
            {
                isInterval = AssertionHelper.IsNumberAxis(actual, actualPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue);
                if (isInterval)
                    return InRange((IEnumerable<XElement>)expected, expectedPlugin, lowValue, highValue, includeLowValue, includeHighValue);
                else
                    return false;
            }
        }

        #endregion
    }

    /// <summary>
    /// Determines whether the element count of one operand is equal to element count of another operand, 
    /// or whether the element count of one operand is equal to number value of another operand
    /// Operand: case 1: both are set style
    /// Operand: case 2: one operand is set, another is operand integer value
    /// Result : true if the element count of one operand is equal to value of represented by another operand, or equal to element count of another operand
    /// </summary>
    class RecordCountIsEqualAssertion_Old : IAssertion
    {
        private bool IsCountEqual(IEnumerable<XElement> enumerableArg, object arg2)
        {
            int count1 = enumerableArg.Count();

            if (AssertionHelper.IsIntNumber(arg2))
            {
                if (count1 == Convert.ToInt32(arg2))
                    return true;
                else
                    return false;
            }
            else
            {
                int count2 = ((IEnumerable<XElement>)arg2).Count();
                if (count1 == count2)
                    return true;
                else
                    return false;
            }
        }

        #region IAssertion Members

        public bool Claim(object actual, object expected, List<FieldMetaData> actualMetaData, List<FieldMetaData> expectedMetaData, ITestDataSource actualPlugin, ITestDataSource expectedPlugin)
        {
            AssertionHelper.VerifyRecordsetCountClaimArgs(actual, expected);

            if (AssertionHelper.IsEnumerable(actual))
            {
                return IsCountEqual((IEnumerable<XElement>)actual, expected);
            }
            else
            {
                return IsCountEqual((IEnumerable<XElement>)expected, actual);
            }
        }

        #endregion
    }


    abstract class RecordCountInRangeAssertionBase : IAssertion
    {
        public abstract DecimalRangeChecker GetDecimalElementRangeChecker();
        public abstract string ConvertExpectedToInterval(object expected);

        private bool IsInRange(object val, int valType, ITestDataSource valPlugin, OracleNumber lowValue, OracleNumber highValue, bool includeLowValue, bool includeHighValue, DecimalRangeChecker checker)
        {
            return AssertionHelper.IsInRange2(val.ToString(), valType, valPlugin, lowValue, highValue, includeLowValue, includeHighValue, checker);
        }

        #region IAssertion Members

        public bool Claim(object actual, object expected, List<FieldMetaData> actualMetaData, List<FieldMetaData> expectedMetaData, ITestDataSource actualPlugin, ITestDataSource expectedPlugin)
        {
            string interval = ConvertExpectedToInterval(expected);
            AssertionHelper.VerifySetCountInIntervalOfNumAxisClaimArgs(actual, actualPlugin, interval, expectedPlugin);

            DecimalRangeChecker checker = GetDecimalElementRangeChecker();
            OracleNumber lowValue, highValue;
            bool includeLowValue, includeHighValue;

            AssertionHelper.IsNumberAxis(interval, expectedPlugin, out lowValue, out highValue, out includeLowValue, out includeHighValue);
            int actualCount = ((IEnumerable<XElement>)actual).Count();
            int actualCountType = actualPlugin.FieldPersistenceService.NumberTypeWhenParseLiteral;
            return IsInRange(actualCount, actualCountType, actualPlugin, lowValue, highValue, includeLowValue, includeHighValue, checker);
        }

        #endregion
    }

    class RecordCountIsEqualAssertion : RecordCountInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsEqual);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string intervalFmt = "[{0},{1}]";
            string interval = string.Format(intervalFmt, expected.ToString(), expected.ToString());
            return interval;
        }
    }


    class RecordCountIsInNumAxisAssertion : RecordCountInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsInNumberAxis);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            //expected should be one interval of number axis
            string interval = expected.ToString();
            return interval;
        }
    }


    class RecordCountIsGreaterAssertion : RecordCountInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsGreater);
        }

     

        public override string ConvertExpectedToInterval(object expected)
        {
            string interval;
            if (AssertionHelper.IsEnumerable(expected))
                interval = ((IEnumerable<XElement>)expected).Count().ToString();
            else
                interval = expected.ToString();

            string intervalFmt = "({0},{1})";
            string intervalStr = string.Format(intervalFmt, interval, "max");
            return intervalStr;
        }
    }


    class RecordCountIsGreaterOrEqualAssertion : RecordCountInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsGreaterOrEqual);
        }

        

        public override string ConvertExpectedToInterval(object expected)
        {
            string interval;
            if (AssertionHelper.IsEnumerable(expected))
                interval = ((IEnumerable<XElement>)expected).Count().ToString();
            else
                interval = expected.ToString();

            string intervalFmt = "[{0},{1})";
            string intervalStr = string.Format(intervalFmt, interval, "max");  
            return intervalStr;
        }
    }


    class RecordCountIsLessAssertion : RecordCountInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsLess);
        }

    

        public override string ConvertExpectedToInterval(object expected)
        {
            string interval;
            if (AssertionHelper.IsEnumerable(expected))
                interval = ((IEnumerable<XElement>)expected).Count().ToString();
            else
                interval = expected.ToString();

            string intervalFmt = "({0},{1})";
            string intervalStr = string.Format(intervalFmt, "min", interval);
            return intervalStr;
        }
    }

    class RecordCountIsLessOrEqualAssertion : RecordCountInRangeAssertionBase
    {
        public override DecimalRangeChecker GetDecimalElementRangeChecker()
        {
            return new DecimalRangeChecker(DecimalRangeCheckerPool.DecimalIsLessOrEqual);
        }

        public override string ConvertExpectedToInterval(object expected)
        {
            string interval;
            if (AssertionHelper.IsEnumerable(expected))
                interval = ((IEnumerable<XElement>)expected).Count().ToString();
            else
                interval = expected.ToString();

            string intervalFmt = "({0},{1}]";
            string intervalStr = string.Format(intervalFmt, "min", interval);
            return intervalStr;
        }
    }


}